<template>
  <div v-if="show" class="upload-modal-overlay" @click="handleOverlayClick">
    <div class="upload-modal" @click.stop>
      <!-- 模态框头部 -->
      <div class="modal-header">
        <div class="header-content">
          <div class="header-icon">📁</div>
          <h3 class="header-title">文档上传</h3>
          <p class="header-subtitle">支持多文件上传，可选择分类</p>
        </div>
        <button class="close-btn" @click="closeModal" :disabled="uploading">
          <span>✕</span>
        </button>
      </div>

      <!-- 模态框内容 -->
      <div class="modal-content">
        <!-- 分类选择 -->
        <div class="form-section">
          <label class="section-label">
            <span class="label-icon">📂</span>
            选择分类
          </label>
          <select 
            v-model="selectedCategory" 
            class="category-select"
            :disabled="uploading"
          >
            <option value="">请选择分类</option>
            <option 
              v-for="category in categories" 
              :key="category.id" 
              :value="category.kno_type"
            >
              {{ category.kno_type }}
            </option>
          </select>
          <div v-if="!selectedCategory" class="form-hint">
            请先选择文档分类
          </div>
        </div>

        <!-- 文件上传区域 -->
        <div class="form-section">
          <label class="section-label">
            <span class="label-icon">📄</span>
            选择文件
          </label>
          <div 
            class="upload-area"
            :class="{ 
              'drag-over': isDragOver, 
              'disabled': !selectedCategory || uploading,
              'has-files': fileList.length > 0
            }"
            @click="triggerFileInput"
            @dragover.prevent="handleDragOver"
            @dragleave.prevent="handleDragLeave"
            @drop.prevent="handleDrop"
          >
            <input 
              ref="fileInput"
              type="file" 
              multiple 
              accept=".pdf,.doc,.docx,.txt,.md,.xlsx,.xls,.pptx,.ppt"
              @change="handleFileSelect"
              style="display: none"
              :disabled="!selectedCategory || uploading"
            />
            
            <div v-if="fileList.length === 0" class="upload-placeholder">
              <div class="upload-icon">📤</div>
              <p class="upload-text">点击或拖拽文件到此处</p>
              <p class="upload-hint">支持 PDF、Word、Excel、PowerPoint、文本文件</p>
            </div>
            
            <div v-else class="upload-summary">
              <div class="summary-icon">📋</div>
              <p class="summary-text">已选择 {{ fileList.length }} 个文件</p>
              <p class="summary-hint">点击重新选择文件</p>
            </div>
          </div>
        </div>

        <!-- 文件列表 -->
        <div v-if="fileList.length > 0" class="form-section">
          <label class="section-label">
            <span class="label-icon">📝</span>
            文件列表
          </label>
          <div class="file-list">
            <div 
              v-for="(file, index) in fileList" 
              :key="index"
              class="file-item"
              :class="{ 
                'uploading': file.status === 'uploading',
                'success': file.status === 'success',
                'error': file.status === 'error'
              }"
            >
              <div class="file-info">
                <div class="file-icon">
                  <span v-if="file.status === 'pending'">📄</span>
                  <span v-else-if="file.status === 'uploading'">⏳</span>
                  <span v-else-if="file.status === 'success'">✅</span>
                  <span v-else-if="file.status === 'error'">❌</span>
                </div>
                <div class="file-details">
                  <p class="file-name">{{ file.name }}</p>
                  <p class="file-size">{{ formatFileSize(file.size) }}</p>
                </div>
              </div>
              
              <div class="file-actions">
                <!-- 进度条 -->
                <div v-if="file.status === 'uploading'" class="progress-bar">
                  <div class="progress-fill" :style="{ width: file.progress + '%' }"></div>
                </div>
                
                <!-- 状态文本 -->
                <div v-else class="file-status">
                  <span v-if="file.status === 'pending'" class="status-pending">等待上传</span>
                  <span v-else-if="file.status === 'success'" class="status-success">上传成功</span>
                  <span v-else-if="file.status === 'error'" class="status-error">上传失败</span>
                </div>
                
                <!-- 删除按钮 -->
                <button 
                  v-if="file.status !== 'uploading'"
                  class="remove-btn"
                  @click="removeFile(index)"
                  :disabled="uploading"
                >
                  🗑️
                </button>
              </div>
            </div>
          </div>
        </div>

        <!-- 上传进度总览 -->
        <div v-if="uploading" class="form-section">
          <div class="upload-progress">
            <div class="progress-header">
              <span class="progress-icon">⏳</span>
              <span class="progress-text">
                {{ uploadingCount > 0 ? '正在上传文档...' : '准备上传...' }}
              </span>
            </div>
            <div class="progress-bar-total">
              <div 
                class="progress-fill-total" 
                :style="{ width: totalProgress + '%' }"
              ></div>
            </div>
            <div class="progress-stats">
              <span>{{ uploadedCount }} / {{ fileList.length }} 个文件</span>
              <span>{{ totalProgress }}%</span>
            </div>
            <div v-if="uploadingCount > 0" class="current-file">
              当前文件: {{ fileList.find(f => f.status === 'uploading')?.name }}
            </div>
          </div>
        </div>
      </div>

      <!-- 模态框底部 -->
      <div class="modal-footer">
        <div class="footer-info">
          <span v-if="fileList.length > 0" class="file-count">
            已选择 {{ fileList.length }} 个文件
          </span>
        </div>
        <div class="footer-actions">
          <button 
            class="btn-cancel" 
            @click="closeModal"
            :disabled="uploading"
          >
            取消
          </button>
          <button 
            class="btn-clear" 
            @click="clearFiles"
            :disabled="fileList.length === 0 || uploading"
          >
            清空
          </button>
          <button 
            class="btn-upload" 
            @click="startUpload"
            :disabled="!canUpload || uploading"
          >
            <span v-if="uploading">上传中...</span>
            <span v-else>开始上传</span>
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted } from 'vue'
import { createKnowledge } from '@/api/knowledge'
import { getKnoTypes } from '@/api/knoType'
import { generateUniqueDocumentId } from '@/utils/tools/idGenerator'
import { getUser } from '@/utils/tools/auth'

// Props
const props = defineProps({
  show: {
    type: Boolean,
    default: false
  }
})

// Emits
const emit = defineEmits(['close', 'upload-success'])

// 响应式数据
const fileInput = ref(null)
const selectedCategory = ref('')
const fileList = ref([])
const categories = ref([])
const uploading = ref(false)
const isDragOver = ref(false)

// 计算属性
const canUpload = computed(() => {
  return selectedCategory.value && fileList.value.length > 0 && !uploading.value
})

const uploadedCount = computed(() => {
  return fileList.value.filter(file => file.status === 'success').length
})

const uploadingCount = computed(() => {
  return fileList.value.filter(file => file.status === 'uploading').length
})

const totalProgress = computed(() => {
  if (fileList.value.length === 0) return 0
  const completedCount = uploadedCount.value
  const currentProgress = uploadingCount.value > 0 ? 
    fileList.value.find(f => f.status === 'uploading')?.progress || 0 : 0
  return Math.round(((completedCount + (currentProgress / 100)) / fileList.value.length) * 100)
})

// 方法
const loadCategories = async () => {
  try {
    const response = await getKnoTypes()
    if (response.code === 200) {
      categories.value = response.data || []
    }
  } catch (error) {
    console.error('获取分类失败:', error)
  }
}

const triggerFileInput = () => {
  if (!selectedCategory.value || uploading.value) return
  fileInput.value?.click()
}

const handleFileSelect = (event) => {
  const files = Array.from(event.target.files)
  addFiles(files)
}

const handleDragOver = (event) => {
  if (!selectedCategory.value || uploading.value) return
  isDragOver.value = true
}

const handleDragLeave = (event) => {
  isDragOver.value = false
}

const handleDrop = (event) => {
  if (!selectedCategory.value || uploading.value) return
  isDragOver.value = false
  
  const files = Array.from(event.dataTransfer.files)
  addFiles(files)
}

const addFiles = (files) => {
  const validFiles = files.filter(file => {
    const validTypes = [
      'application/pdf',
      'application/msword',
      'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
      'text/plain',
      'text/markdown',
      'application/vnd.ms-excel',
      'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      'application/vnd.ms-powerpoint',
      'application/vnd.openxmlformats-officedocument.presentationml.presentation'
    ]
    return validTypes.includes(file.type) || file.name.match(/\.(pdf|doc|docx|txt|md|xlsx|xls|pptx|ppt)$/i)
  })

  validFiles.forEach(file => {
    // 检查是否已存在相同文件
    const exists = fileList.value.some(f => f.name === file.name && f.size === file.size)
    if (!exists) {
      fileList.value.push({
        file: file,
        name: file.name,
        size: file.size,
        status: 'pending',
        progress: 0,
        error: null
      })
    }
  })
}

const removeFile = (index) => {
  fileList.value.splice(index, 1)
}

const clearFiles = () => {
  fileList.value = []
  if (fileInput.value) {
    fileInput.value.value = ''
  }
}

const formatFileSize = (bytes) => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

const startUpload = async () => {
  if (!canUpload.value) return
  
  uploading.value = true
  
  // 重置所有文件状态
  fileList.value.forEach(file => {
    file.status = 'pending'
    file.progress = 0
    file.error = null
  })
  
  // 逐个上传文件，每个文件调用一次API请求，添加延迟避免连接问题
  for (let i = 0; i < fileList.value.length; i++) {
    await uploadSingleFile(fileList.value[i])
    
    // 在文件之间添加延迟，避免MySQL连接池耗尽
    if (i < fileList.value.length - 1) {
      await new Promise(resolve => setTimeout(resolve, 500))
    }
  }
  
  uploading.value = false
  
  // 检查上传结果
  const successCount = fileList.value.filter(f => f.status === 'success').length
  const errorCount = fileList.value.filter(f => f.status === 'error').length
  
  if (successCount > 0) {
    emit('upload-success', {
      success: successCount,
      error: errorCount,
      total: fileList.value.length
    })
    // 上传成功后关闭弹窗
    closeModal()
  }
}

const uploadSingleFile = async (fileItem) => {
  try {
    fileItem.status = 'uploading'
    fileItem.progress = 0
    
    // 模拟文件读取为base64
    const base64Content = await readFileAsBase64(fileItem.file)
    
    // 生成符合数据库约束的数据
    const now = new Date()
    const knoId = generateKnowledgeId()
    
    // 获取当前登录用户信息
    const currentUser = getUser()
    const userName = currentUser?.username || '未知用户'
    
    // 构建上传数据 - 确保符合数据库约束
    const uploadData = {
      kno_id: knoId,
      kno_title: fileItem.name.substring(0, 255), // 保留完整文件名（包括扩展名）
      kno_type: selectedCategory.value.substring(0, 255),
      kno_url: base64Content,
      kno_authid: userName,
      kno_style: 3,
      kno_createtime: now.toISOString().replace('T', ' ').replace('Z', ''),
      kno_updatetime: now.toISOString().replace('T', ' ').replace('Z', '')
    }
    
    // 模拟上传进度
    const progressInterval = setInterval(() => {
      if (fileItem.progress < 90) {
        fileItem.progress += Math.random() * 20
      }
    }, 200)
    
    // 发送请求
    const response = await createKnowledge(uploadData)
    
    clearInterval(progressInterval)
    fileItem.progress = 100
    
    if (response && response.code === 200) {
      fileItem.status = 'success'
    } else {
      throw new Error(response?.message || '上传失败')
    }
    
  } catch (error) {
    fileItem.status = 'error'
    fileItem.error = error.message || '上传失败'
    fileItem.progress = 0
  }
}

const readFileAsBase64 = (file) => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.onload = () => {
      // 移除data:type;base64,前缀
      const base64 = reader.result.split(',')[1]
      resolve(base64)
    }
    reader.onerror = reject
    reader.readAsDataURL(file)
  })
}

const generateKnowledgeId = () => {
  // 使用专门的文档ID生成器，确保唯一性
  return generateUniqueDocumentId()
}

const handleOverlayClick = (event) => {
  if (event.target === event.currentTarget && !uploading.value) {
    closeModal()
  }
}

const closeModal = () => {
  if (uploading.value) return
  
  emit('close')
  
  // 重置状态
  setTimeout(() => {
    selectedCategory.value = ''
    fileList.value = []
    isDragOver.value = false
    if (fileInput.value) {
      fileInput.value.value = ''
    }
  }, 300)
}

// 监听show变化
watch(() => props.show, (newVal) => {
  if (newVal) {
    loadCategories()
  }
})

// 生命周期
onMounted(() => {
  if (props.show) {
    loadCategories()
  }
})
</script>

<style scoped>
.upload-modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  animation: fadeIn 0.3s ease-out;
}

.upload-modal {
  background: var(--bg-primary);
  border-radius: 1rem;
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
  width: 90%;
  max-width: 800px;
  max-height: 90vh;
  overflow: hidden;
  animation: slideIn 0.3s ease-out;
  border: 1px solid var(--border-color);
  color: var(--text-primary);
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1.5rem 2rem;
  border-bottom: 1px solid var(--border-color);
  background: var(--bg-secondary);
}

.header-content {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.header-icon {
  font-size: 1.5rem;
}

.header-title {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--text-primary);
}

.header-subtitle {
  margin: 0;
  font-size: 0.875rem;
  color: var(--text-secondary);
}

.close-btn {
  background: var(--bg-tertiary);
  border: none;
  font-size: 1rem;
  cursor: pointer;
  color: var(--text-muted);
  padding: 0.5rem;
  border-radius: 0.5rem;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;
}

.close-btn:hover:not(:disabled) {
  background: var(--border-color);
  color: var(--text-primary);
  transform: scale(1.05);
}

.close-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.modal-content {
  padding: 2rem;
  max-height: 60vh;
  overflow-y: auto;
}

.form-section {
  margin-bottom: 2rem;
}

.section-label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
  font-weight: 600;
  color: var(--text-primary);
  font-size: 0.875rem;
}

.label-icon {
  font-size: 1rem;
}

.category-select {
  width: 100%;
  padding: 0.875rem 1rem;
  border: 2px solid var(--border-color);
  border-radius: 0.5rem;
  background: var(--bg-primary);
  color: var(--text-primary);
  font-size: 0.875rem;
  transition: all 0.2s ease;
  box-sizing: border-box;
}

.category-select:focus {
  outline: none;
  border-color: var(--accent-color);
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}

.category-select:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.form-hint {
  display: block;
  margin-top: 0.5rem;
  font-size: 0.75rem;
  color: var(--text-muted);
  font-style: italic;
}

.upload-area {
  border: 2px dashed var(--border-color);
  border-radius: 0.75rem;
  padding: 2rem;
  text-align: center;
  cursor: pointer;
  transition: all 0.3s ease;
  background: var(--bg-secondary);
  min-height: 120px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.upload-area:hover:not(.disabled) {
  border-color: var(--accent-color);
  background: var(--bg-tertiary);
}

.upload-area.drag-over {
  border-color: var(--accent-color);
  background: var(--bg-tertiary);
  transform: scale(1.02);
}

.upload-area.disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.upload-area.has-files {
  border-style: solid;
  border-color: var(--accent-color);
  background: var(--bg-tertiary);
}

.upload-placeholder,
.upload-summary {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
}

.upload-icon,
.summary-icon {
  font-size: 2rem;
  opacity: 0.7;
}

.upload-text,
.summary-text {
  margin: 0;
  font-size: 1rem;
  font-weight: 500;
  color: var(--text-primary);
}

.upload-hint,
.summary-hint {
  margin: 0;
  font-size: 0.875rem;
  color: var(--text-secondary);
}

.file-list {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  max-height: 300px;
  overflow-y: auto;
}

.file-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem;
  border: 1px solid var(--border-color);
  border-radius: 0.5rem;
  background: var(--bg-primary);
  transition: all 0.2s ease;
}

.file-item.uploading {
  border-color: var(--accent-color);
  background: var(--bg-tertiary);
}

.file-item.success {
  border-color: #10b981;
  background: #f0fdf4;
}

.file-item.error {
  border-color: #ef4444;
  background: #fef2f2;
}

.file-info {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex: 1;
}

.file-icon {
  font-size: 1.25rem;
  width: 24px;
  text-align: center;
}

.file-details {
  flex: 1;
}

.file-name {
  margin: 0 0 0.25rem 0;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--text-primary);
  word-break: break-all;
}

.file-size {
  margin: 0;
  font-size: 0.75rem;
  color: var(--text-secondary);
}

.file-actions {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.progress-bar {
  width: 100px;
  height: 6px;
  background: var(--border-color);
  border-radius: 3px;
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  background: var(--accent-color);
  transition: width 0.3s ease;
}

.file-status {
  font-size: 0.75rem;
  font-weight: 500;
}

.status-pending {
  color: var(--text-muted);
}

.status-success {
  color: #10b981;
}

.status-error {
  color: #ef4444;
}

.remove-btn {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 0.875rem;
  padding: 0.25rem;
  border-radius: 0.25rem;
  transition: all 0.2s ease;
}

.remove-btn:hover:not(:disabled) {
  background: var(--bg-tertiary);
}

.remove-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.upload-progress {
  padding: 1rem;
  border: 1px solid var(--border-color);
  border-radius: 0.5rem;
  background: var(--bg-secondary);
}

.progress-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}

.progress-icon {
  font-size: 1rem;
}

.progress-text {
  margin: 0;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--text-primary);
}

.progress-bar-total {
  width: 100%;
  height: 8px;
  background: var(--border-color);
  border-radius: 4px;
  overflow: hidden;
  margin-bottom: 0.5rem;
}

.progress-fill-total {
  height: 100%;
  background: linear-gradient(90deg, var(--accent-color), #10b981);
  transition: width 0.3s ease;
}

.progress-stats {
  display: flex;
  justify-content: space-between;
  font-size: 0.75rem;
  color: var(--text-secondary);
}

.current-file {
  margin-top: 0.5rem;
  font-size: 0.75rem;
  color: var(--text-primary);
  font-weight: 500;
  text-align: center;
  padding: 0.25rem 0.5rem;
  background: var(--bg-tertiary);
  border-radius: 0.25rem;
}

.modal-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1.5rem 2rem;
  border-top: 1px solid var(--border-color);
  background: var(--bg-secondary);
}

.footer-info {
  flex: 1;
}

.file-count {
  font-size: 0.875rem;
  color: var(--text-secondary);
}

.footer-actions {
  display: flex;
  gap: 1rem;
}

.btn-cancel,
.btn-clear,
.btn-upload {
  padding: 0.75rem 1.5rem;
  border-radius: 0.5rem;
  font-weight: 500;
  font-size: 0.875rem;
  cursor: pointer;
  transition: all 0.2s ease;
  border: none;
}

.btn-cancel {
  background: var(--bg-tertiary);
  color: var(--text-primary);
  border: 1px solid var(--border-color);
}

.btn-cancel:hover:not(:disabled) {
  background: var(--border-color);
}

.btn-clear {
  background: #fef3c7;
  color: #d97706;
  border: 1px solid #fde68a;
}

.btn-clear:hover:not(:disabled) {
  background: #fde68a;
}

.btn-upload {
  background: var(--accent-color);
  color: white;
  box-shadow: 0 4px 14px 0 rgba(59, 130, 246, 0.3);
}

.btn-upload:hover:not(:disabled) {
  background: var(--accent-hover);
  transform: translateY(-1px);
  box-shadow: 0 6px 20px 0 rgba(59, 130, 246, 0.4);
}

.btn-cancel:disabled,
.btn-clear:disabled,
.btn-upload:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none;
}

/* 动画效果 */
@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes slideIn {
  from {
    opacity: 0;
    transform: translateY(-20px) scale(0.95);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

/* 响应式设计 */
@media (max-width: 768px) {
  .upload-modal {
    width: 95%;
    margin: 1rem;
  }
  
  .modal-header,
  .modal-content,
  .modal-footer {
    padding: 1rem;
  }
  
  .footer-actions {
    flex-direction: column;
    gap: 0.5rem;
  }
  
  .btn-cancel,
  .btn-clear,
  .btn-upload {
    width: 100%;
  }
  
  .file-item {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.75rem;
  }
  
  .file-actions {
    width: 100%;
    justify-content: space-between;
  }
}
</style>
